package com.chenfan.magic.tags.handler;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.chenfan.magic.base.Kv;
import com.chenfan.magic.constant.RuntimeConstant;
import com.chenfan.magic.core.IdcEngineEntry;
import com.chenfan.magic.entity.Isv;
import com.chenfan.magic.entity.MQLModel;
import com.chenfan.magic.entity.TTLDetailModel;
import com.chenfan.magic.entity.TTLModel;
import com.chenfan.magic.resolver._MainResolver;
import com.chenfan.magic.tags.TagRedis;
import com.chenfan.magic.utils.FastJsonKit;
import com.google.common.collect.Maps;
import lombok.AllArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * template 标签处理器
 *
 * @author  周夕
 * @date 2020-02-26 18:21
 */
@Component
@AllArgsConstructor
public class TagRedisHandler {

    private StringRedisTemplate stringRedisTemplate;

    /**
     * 执行入口
     *
     * @param mqlModel
     * @param key
     * @return
     */
    public boolean execute(
            MQLModel mqlModel,
            Map<String, Object> idcRuntimePool,
            String key,
            Map<String, Object> paramMap,
            Map<String, Object> resMap,
            Map<String, Object> eofMap,
            Map<String, Object> resolveMap,
            Map<String, Object> attributeMap,
            Kv kv,
            TTLModel ttlModel
    ) {
        TTLDetailModel ttlDetailModel = new TTLDetailModel();
        String prefixKey = TagRedis.tagNames + "#" + key;
        ttlDetailModel.start(prefixKey);
        TagRedis redisModel = mqlModel.getRedis(key, idcRuntimePool, paramMap, attributeMap);
        kv.set(RuntimeConstant.RUNTIME_EXECUTE_VAR_KEY_PREFIXKEY, prefixKey);
        kv.set(RuntimeConstant.RUNTIME_EXECUTE_VAR_KEY_RESPOND, redisModel.getRespond());
        kv.set(RuntimeConstant.RUNTIME_EXECUTE_VAR_KEY_RESULTKEY, redisModel.getResultKey());
        Map<String, Object> res = Maps.newHashMap();
        //防止引用检测
        String json = JSON.toJSONString(paramMap, SerializerFeature.DisableCircularReferenceDetect);
        Map<String, Object> pm = FastJsonKit.jsonstring2Map(json);
        pm.remove("#params");
        pm.remove("#context");

        res = run(idcRuntimePool, ttlModel, prefixKey, redisModel, paramMap);
        res.put("#params", pm);
        resMap.put(prefixKey, res);
        paramMap.putAll(attributeMap);
        paramMap.putAll(res);
        resolveMap.put(redisModel.getResultKey(), redisModel.getContext());

        ttlModel.getExecuter().put(ttlDetailModel.end());
        return true;
    }

    /**
     * redis标签处理
     *
     * @param redisModel
     * @param paramMap
     * @return
     */
    public Map<String, Object> run(Map<String, Object> idcRuntimePool, TTLModel ttlModel, String prefixKey, TagRedis redisModel, Map<String, Object> paramMap) {
        Map<String, Object> res = Maps.newHashMap();
        String value = new _MainResolver().resolveScope(idcRuntimePool, ttlModel, prefixKey, redisModel, paramMap);
        try {
            Isv isv = (Isv) idcRuntimePool.get(RuntimeConstant.RUNTIME_ISV);
            String redisKey = isv.getAppNamespace() + "_" + redisModel.getKey();
            //如果值不为空, 则更新redis, 否则, 取值.
            if ("set".equalsIgnoreCase(redisModel.getCmd())) {
                stringRedisTemplate.opsForValue().set(redisKey, value, (redisModel.getExpire() == 0L ? 86400L : (redisModel.getExpire())), TimeUnit.SECONDS);
            } else {
                value = stringRedisTemplate.opsForValue().get(redisKey);
            }
            res.put(redisModel.getResultKey(), value);
            res.put("#context", value);
        } catch (Exception e) {
            e.printStackTrace();
            IdcEngineEntry.throwException(idcRuntimePool, null, "redis动态调度器异常! \n", e);
        }
        return res;
    }
}
